#include <bits/stdc++.h>

class IncorrectGameStateException : public std::exception {
public:
    const char *what() const noexcept override;
};

class IncorrectGameMoveException : public std::exception {
public:
    const char *what() const noexcept override;
};

template <typename Result=int, class Iter>
auto countObjects(Iter begin, Iter end) {
    std::unordered_map<typename std::iterator_traits<Iter>::value_type, Result>
        result;
    for (auto it = begin; it != end; ++it)
        ++result[*it];
    return result;
}

class GameState {
    std::vector<int> state_;
    std::unordered_map<int, int> cnt_;
    template <class Iter>
    static inline std::vector<int> createVector_(Iter it, std::size_t n) {
        std::vector<int> result(n);
        std::copy_n(it, n, result.begin());
        return result;
    }
public:
    GameState(std::vector<int> state, bool shouldBeUnique = true)
        : state_(std::move(state)),
          cnt_(countObjects(state_.begin(), state_.end())) {
        if (std::unordered_set<int>(state_.begin(),
                                    state_.end()).size() != state_.size()
            && shouldBeUnique)
            throw IncorrectGameStateException();
    }
    template <class Iter>
    GameState(Iter begin, Iter end, bool shouldBeUnique = true)
        : GameState(std::vector<int>(begin, end), shouldBeUnique) {}
    template <typename Iter>
    GameState(Iter begin, std::size_t n, bool shouldBeUnique = true)
        : GameState(createVector_(begin, n), shouldBeUnique) {}
    
    GameState(const GameState &) = default;
    GameState(GameState &&) noexcept = default;
    GameState() = default;
    GameState &operator = (const GameState &) = default;
    GameState &operator = (GameState &&) noexcept = default;

    template <class... Args>
    void assign(Args &&... args) { // I'm too lazy to write 3 functions
        *this = std::move(GameState(args...));
    }
    std::pair<std::size_t, std::size_t>
    move(const std::vector<int> &move) const;
    bool goodMove(const std::vector<int> &move) {
        return state_ == move;
    }
    std::size_t size() const noexcept {
        return state_.size();
    }
};

const char *IncorrectGameStateException::what() const noexcept {
    return "Game state is incorrect";
}


const char *IncorrectGameMoveException::what() const noexcept {
    return "Game move is incorrect";
}

std::pair<std::size_t, std::size_t>
GameState::move(const std::vector<int> &move) const {
    if (move.size() != state_.size())
        throw IncorrectGameMoveException();
    std::size_t bulls = 0, cows = 0;
    auto cnt = cnt_;
    for (size_t i = 0; i < state_.size(); ++i) {
        if (move[i] == state_[i])
            ++bulls;
    }
    for (size_t i = 0; i < state_.size(); ++i) {
        if (cnt[move[i]] != 0) {
            --cnt[move[i]];
            ++cows;
        }
    }
    return {bulls, cows}; 
}

GameState generateRandomState() {
    auto seed = std::random_device()();
    std::default_random_engine eng(seed);
    std::vector<int> result;
    for (int i = 0; i < 4; ++i) {
        std::uniform_int_distribution<> dist(0, 9);
        result.push_back(dist(eng));
    }
    return {result, false};
}

GameState readState() {
    std::size_t n;
    using std::cin;
    using std::cout;
    using std::endl;
    cout << "Enter length of sequences: ";
    cin >> n;
    GameState state;; 
    for (;;) {
        cout << "Enter sequence itself, separated by spaces: ";
        try {
            state.assign(std::istream_iterator<int>(std::cin), n);
            break;
        } catch (IncorrectGameStateException e) {
            cout << "Incorrect sequence!" << endl;
        }
    } 
    return state;
}

// For testing only
int main() {
    using std::cin;
    using std::cout;
    using std::endl;
    GameState state = generateRandomState();
    for (;;) {
        cout << "Enter your move: ";
        std::pair<std::size_t, std::size_t> moveResult;
        try {
            moveResult = state.move(std::istream_iterator<int>(std::cin));
        } catch (IncorrectGameMoveException e) {
            cout << "Incorrect move!" << endl;
            continue;
        }
        if (moveResult.first == state.size()) {
            break;
        } else {
            cout << moveResult.first << " : " << moveResult.second << endl;
        }
    }
    cout << "You won! Game over." << endl;
}

